package com.photoeditor.demo.ui.widget.collage;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;

import com.android.videolib.CombineBean;
import com.android.videolib.MediaCodecHelper;
import com.common.base.log.DLog;
import com.photoeditor.demo.model.bean.BitmapBean;
import com.photoeditor.demo.model.image.collage.templet.CollagePoints;
import com.photoeditor.demo.model.image.collage.templet.CollageTemplet;
import com.photoeditor.demo.model.image.collage.templet.DragPoint;
import com.photoeditor.demo.model.image.collage.templet.Ratio;
import com.photoeditor.demo.model.image.collage.templet.RoundPathUtil;
import com.photoeditor.demo.model.image.collage.templet.attr.IStatus;
import com.photoeditor.demo.model.image.collage.util.CollageGestureRecognizer;
import com.photoeditor.demo.model.image.util.ImageHelper;
import com.photoeditor.demo.ui.widget.TextureVideoView;
import com.photoeditor.demo.util.Gif2VideoUtils;
import com.photoeditor.demo.util.ImageRectUtils;
import com.photoeditor.demo.util.MediaTypeUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import pl.droidsonroids.gif.GifBitmap;

/**
 * 拼接的父View， 他会处理所有的点击事件并分发给需要的CollagePathView
 */
public class CollageRelativeLayout extends RelativeLayout implements View.OnTouchListener, CollageGestureRecognizer.Listener, GifBitmap.OnGifRefreshListener {

    private Context mActivity;

    private ICollage mCollage;

    //当前的模板
    private CollageTemplet mTemplet;

    //是否初始化
    private boolean mIsInit = false;

    //View 的Rect  相对于整个屏幕的位置
    private RectF mViewRect;

    //子View的显示区域  相对于这个View的位置
    private RectF mAllChildRect;

    //所有子View的默认位置  相对于这个View的位置
    private ArrayList<RectF> mChildBoundRect;

    //保存拼接的所有图片
    private ArrayList<Bitmap> mSourceBitmaps;
    // 所有图片基本信息
    private ArrayList<BitmapBean> mBitmapBeenList = new ArrayList<>();

    private boolean mIsSingeleBitmapMode = false;

    //用于存储当前圆角的Progress  0 - 100
    private int mRoundProgress = 0;

    //用于存储当前距离的Progress  0 - 100
    private int mDistanceProgress = 0;

    //当前的
    private Ratio.RATIO mType;

    //用于绘制背景 mColorBgPaint用于绘制默认的背景 和 color 背景 mBgPaint用于绘制其他背景
    private Paint mColorBgPaint;
    private int mBgColor;
    private Paint mBgPaint;
    private boolean mIsColorBg = true;

    //背景图片
    private Bitmap mBgBitmap;
    private BitmapBean mBgBitmapBean;
    private GifBitmap mGifBitmap;
    private GifBitmap mGifBitmapForRender;

    //缓存正在绘制的图片，主要用于视频合成的优化，防止重复创建位图
    private Bitmap mCacheBitmap;


    //Mirror新增
    public final static int MODE_COLLAGE = 0;
    public final static int MODE_MIRROR = 1;
    private int mMode = MODE_COLLAGE;
    private boolean mShareOperation = false;//是否共享操作

    private boolean mIsList = false;
    private boolean mIsVideoPlayall = true;

    private DragPointView mDragPointView;
    private boolean mIsInDrag;
    // 有distance距离的拖拽点的坐标，用于显示
    private List<com.photoeditor.demo.model.image.collage.templet.DragPoint> mDragPointList;
    // 无distance距离的拖拽点的坐标，用于实际拖拽使用
    private List<com.photoeditor.demo.model.image.collage.templet.DragPoint> mDragPointListNoDistance;

    private TextureVideoView.MediaPlayerCallback mMediaPlayerCallback;
    private boolean mUseBg = false;

    private boolean mFromMirror = false;

    public CollageRelativeLayout(Context context) {
        this(context, null);
    }

    public CollageRelativeLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CollageRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initWidthAttr(attrs);
    }

    public void setMediaPlayerCallback(TextureVideoView.MediaPlayerCallback callback) {
        mMediaPlayerCallback = callback;
    }

    //构造函数的初始化
    private void initWidthAttr(AttributeSet attrs) {
        setWillNotDraw(false);
        mActivity = getContext();
        mCollage = (ICollage) getContext();
        mType = Ratio.RATIO.RATIO_1_1;
        mViewRect = new RectF();
        mAllChildRect = new RectF();
        mChildBoundRect = new ArrayList<RectF>();

        mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBgPaint.setStyle(Paint.Style.FILL);

        mBgColor = Color.WHITE;
        mColorBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mColorBgPaint.setColor(mBgColor);
        mColorBgPaint.setStyle(Paint.Style.FILL);

        setOnTouchListener(this);
        mGestureRecognizer = new CollageGestureRecognizer(getContext(), this);
    }

    //onlayout 完成后的初始化
    private void init(RectF rectF) {
        if (mIsFilter) {
            return;
        }
        if (!mIsInit || !mViewRect.equals(rectF)) {
            mIsInit = true;
            mViewRect = rectF;
            if (isList()) {
            } else {
                invalidateCollage();
            }
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        if (changed) {
            init(ImageRectUtils.getViewRect(this));
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mIsInit) {
            if (mIsColorBg) {
                canvas.drawRect(mAllChildRect, mColorBgPaint);
            } else {
                mColorBgPaint.setColor(Color.WHITE);
                canvas.drawRect(mAllChildRect, mColorBgPaint);
                canvas.drawRect(mAllChildRect, mBgPaint);
            }
        }
    }

    private Bitmap mDrawCacheBitmap;

    @Override
    protected void dispatchDraw(Canvas canvas) {
        if (mDrawCacheBitmap != null && !mDrawCacheBitmap.isRecycled()) {
            canvas.drawBitmap(mDrawCacheBitmap, 0, 0, null);
        } else {
            super.dispatchDraw(canvas);
        }
    }

    public void buildDrawCache() {
        if (mDrawCacheBitmap != null && !mDrawCacheBitmap.isRecycled()) {
            return;
        }
        buildDrawingCache();
        mDrawCacheBitmap = getDrawingCache();
        invalidate();
    }

    public void releaseDrawCache() {
        if (mDrawCacheBitmap != null && !mDrawCacheBitmap.isRecycled()) {
            destroyDrawingCache();
            mDrawCacheBitmap.recycle();
            mDrawCacheBitmap = null;
            invalidate();
        }
    }

    @Override
    public void invalidate() {
        super.invalidate();
    }

    @Override
    public void postInvalidate() {
        super.postInvalidate();
    }

    /**
     * 设置当前的比例
     *
     * @param type
     */
    public void setType(Ratio.RATIO type) {
        if (mType.ordinal() != type.ordinal()) {
            mType = type;
            if (mIsInit) {
                invalidateType();
            }
        }
    }

    /**
     * 设置拼接的原图
     *
     * @param bitmaps
     */
    public void setSourceBitmaps(ArrayList<Bitmap> bitmaps) {
        if (mSourceBitmaps == null) {
            mSourceBitmaps = new ArrayList<>();
        }
        mSourceBitmaps.clear();
        mSourceBitmaps.addAll(bitmaps);
        if (bitmaps.size() == 1) {
            mIsSingeleBitmapMode = true;
        }
        if (mIsInit) {
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                if (!(getChildAt(i) instanceof ICollagePathView)) {
                    continue;
                }
                ICollagePathView pathView = (ICollagePathView) getChildAt(i);
                if (mIsSingeleBitmapMode) {
                    pathView.setSourceBitmap(mSourceBitmaps.get(0));
                } else {
                    pathView.setSourceBitmap(mSourceBitmaps.get(i));
                }
            }
        }
    }

    public void setSourceBitmapBeans(ArrayList<BitmapBean> bitmapBeans) {
        mBitmapBeenList = bitmapBeans;
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            ICollagePathView pathView = (ICollagePathView) getChildAt(i);
            if (i >= mBitmapBeenList.size()) {
                pathView.setBitmapBean(null);
            } else {
                pathView.setBitmapBean(mBitmapBeenList.get(i));
            }
        }
    }

    /**
     * 设置拼接的原图,镜像里使用
     *
     * @param bitmap
     */
    public void setSourceBitmaps(Bitmap bitmap) {
        mSourceBitmaps = new ArrayList<Bitmap>(1);
        mSourceBitmaps.add(bitmap);
        if (mSourceBitmaps.size() == 1) {
            mIsSingeleBitmapMode = true;
        }
        if (mIsInit) {
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                if (!(getChildAt(i) instanceof ICollagePathView)) {
                    continue;
                }
                ICollagePathView pathView = (ICollagePathView) getChildAt(i);
                if (mIsSingeleBitmapMode) {
                    pathView.setSourceBitmap(mSourceBitmaps.get(0));
                } else {
                    pathView.setSourceBitmap(mSourceBitmaps.get(i));
                }
            }
        }
    }

    public void setIsSingeleBitmapMode(boolean single) {
        mIsSingeleBitmapMode = true;
    }

    /**
     * 设置新的模板
     *
     * @param collageTemplet
     */
    public void setTemplet(CollageTemplet collageTemplet) {
        if (collageTemplet == null) {
            return;
        }
        boolean isSample = mTemplet != null && (collageTemplet.getCollageNumber() == mTemplet.getCollageNumber());
        mTemplet = collageTemplet.clone();
        if (mIsInit) {
            if (isSample) {//如果个数一样则可以共享View
                if (mIsSingeleBitmapMode) {
//                    单张图片的时普通拼图切换模板,都重新载入原图.
                    invalidateCollage();
                } else {
                    initAllChildView();
                }
            } else {
                invalidateCollage();
            }
        }
    }

    public int getTempletNumber() {
        if (mTemplet != null) {
            return mTemplet.getCollageNumber();
        }
        return 0;
    }

    /**
     * 设置间距的进度
     *
     * @param progress
     */
    public void setDistanceProgress(int progress) {
        mDistanceProgress = progress;
        if (mIsInit) {
            invalidateChildViewSize();
        }
    }

    /**
     * 设置圆角的进度
     *
     * @param progress
     */
    public void setRoundProgress(int progress) {
        mRoundProgress = progress;
        if (mIsInit) {
            invalidateRound();
        }
    }

    public int getRoundProgress() {
        return mRoundProgress;
    }

    public int getDistanceProgress() {
        return mDistanceProgress;
    }


    /**
     * 保证RectF合适
     *
     * @param rectF
     */
    private void checkRectF(RectF rectF) {
        int width = (int) Math.ceil(rectF.width());
        int height = (int) Math.ceil(rectF.height());
        int left = (int) rectF.left;
        int top = (int) rectF.top;
        if (width + left < rectF.right) {
            width += 1;
        }
        if (height + top < rectF.bottom) {
            height += 1;
        }
        rectF.set(left, top, width + left, height + top);
    }

    /**
     * 刷新整个界面
     */
    public void invalidateCollage() {
        if (mTemplet != null) {
            mChildBoundRect.clear();
            mCacheBitmap = null;
            removeAllViews();
            int count = mTemplet.getCollageNumber();
            float ratio = Ratio.SCALE_FACTOR[mType.ordinal()];
            if (mViewRect.width() / ratio <= mViewRect.height()) {//变换后高变小了,需要重新调整高度(变小)
                mAllChildRect.left = 0;
                mAllChildRect.top = (mViewRect.height() - mViewRect.width() / ratio) / 2;
                mAllChildRect.right = mViewRect.width();
                mAllChildRect.bottom = mAllChildRect.top + mViewRect.width() / ratio;
            } else {
                mAllChildRect.left = (mViewRect.width() - mViewRect.height() * ratio) / 2;
                mAllChildRect.top = 0;
                mAllChildRect.right = mAllChildRect.left + mViewRect.height() * ratio;
                mAllChildRect.bottom = mViewRect.height();
            }
            for (int i = 0; i < count; i++) {
                CollagePoints collage = mTemplet.getCollagePoints(i);
                IStatus preAttr = mTemplet.getPreStatus(i);
                RectF boundRect = collage.getBoundRect();
                RectF childRect = new RectF(mAllChildRect.left + boundRect.left * mAllChildRect.width(), mAllChildRect.top + boundRect.top * mAllChildRect.height(),
                        mAllChildRect.left + boundRect.right * mAllChildRect.width(), mAllChildRect.top + boundRect.bottom * mAllChildRect.height());

                checkRectF(childRect);
                mChildBoundRect.add(childRect);
                if (mDistanceProgress == 0) {
                    Path path = RoundPathUtil.getFitPath(collage, mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
                    RectF current = new RectF(childRect);

                    LayoutParams lp = new LayoutParams((int) current.width(), (int) current.height());
                    lp.topMargin = (int) current.top;
                    lp.leftMargin = (int) current.left;

                    BitmapBean bean = null;
                    if (mBitmapBeenList != null && mBitmapBeenList.size() > 0) {
                        if (mIsSingeleBitmapMode) {
                            bean = mBitmapBeenList.get(0);
                        } else {
                            bean = mBitmapBeenList.get(i);
                        }
                    }
                    ICollagePathView pathView;
                    if (bean.mType == MediaTypeUtil.TYPE_VIDEO) {
                        CollageVideoView videoView = new CollageVideoView(getContext(), childRect, path, current, mAllChildRect, collage, preAttr);
                        videoView.setVideoPath(bean.mPath);
                        videoView.setMediaPlayerCallback(mMediaPlayerCallback, i);
                        pathView = videoView;
                    } else {
                        pathView = new CollagePathView(getContext(), childRect, path, current, mAllChildRect, collage, preAttr);
                        ((CollagePathView) pathView).setFromMirror(mFromMirror);
                        ((CollagePathView) pathView).setMediaPlayerCallback(mMediaPlayerCallback, i);
                    }
                    if (mSourceBitmaps != null && mSourceBitmaps.size() > 0) {
                        if (mIsSingeleBitmapMode) {
                            pathView.setSourceBitmap(mSourceBitmaps.get(0));
                        } else {
                            pathView.setSourceBitmap(mSourceBitmaps.get(i));
                        }
                    }
                    addView((View) pathView, lp);
                } else {
                    Path path = RoundPathUtil.getFitPath(collage, mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
                    RectF pathBound = new RectF();
                    path.computeBounds(pathBound, false);
                    RectF current = new RectF(pathBound);
                    current.offset(mAllChildRect.left, mAllChildRect.top);

                    int width = (int) Math.ceil(current.width());
                    int height = (int) Math.ceil(current.height());
                    int left = (int) current.left;
                    int top = (int) current.top;
                    if (width + left < current.right) {
                        width += 1;
                    }
                    if (height + top < current.bottom) {
                        height += 1;
                    }
                    LayoutParams lp = new LayoutParams(width, height);
                    lp.topMargin = top;
                    lp.leftMargin = left;
                    current.set(left, top, width + left, height + top);

                    BitmapBean bean = null;
                    if (mBitmapBeenList != null && mBitmapBeenList.size() > 0) {
                        if (mIsSingeleBitmapMode) {
                            bean = mBitmapBeenList.get(0);
                        } else {
                            bean = mBitmapBeenList.get(i);
                        }
                    }
                    ICollagePathView pathView;
                    if (bean.mType == MediaTypeUtil.TYPE_VIDEO) {
                        CollageVideoView videoView = new CollageVideoView(getContext(), childRect, path, current, mAllChildRect, collage, preAttr);
                        videoView.setVideoPath(bean.mPath);
                        videoView.setMediaPlayerCallback(mMediaPlayerCallback, i);
                        pathView = videoView;
                    } else {
                        pathView = new CollagePathView(getContext(), childRect, path, current, mAllChildRect, collage, preAttr);
                        ((CollagePathView) pathView).setFromMirror(mFromMirror);
                        ((CollagePathView) pathView).setMediaPlayerCallback(mMediaPlayerCallback, i);
                    }
                    if (mSourceBitmaps != null && mSourceBitmaps.size() > 0) {
                        if (mIsSingeleBitmapMode) {
                            pathView.setSourceBitmap(mSourceBitmaps.get(0));
                        } else {
                            pathView.setSourceBitmap(mSourceBitmaps.get(i));
                        }
                    }
                    addView((View) pathView, lp);
                }
            }
            // 刷新gif图片
            for (int i = 0; i < count; i++) {
                if (!(getChildAt(i) instanceof ICollagePathView)) {
                    continue;
                }
                ICollagePathView pathView = (ICollagePathView) getChildAt(i);
                BitmapBean bean = null;
                if (mBitmapBeenList != null && mBitmapBeenList.size() > 0) {
                    if (mIsSingeleBitmapMode) {
                        bean = mBitmapBeenList.get(0);
                    } else {
                        bean = mBitmapBeenList.get(i);
                    }
                }
                pathView.setBitmapBean(bean);
            }
            startVideo(mIsVideoPlayall);

            // 添加view用于显示拖拽的点
            mDragPointView = new DragPointView(getContext());
            LayoutParams lp = new LayoutParams((int) mAllChildRect.width(), (int) mAllChildRect.height());
            lp.topMargin = (int) mAllChildRect.top;
            lp.leftMargin = (int) mAllChildRect.left;
            addView(mDragPointView, lp);
        }
    }


    /**
     * 刷新整个界面
     */
    public void invalidateType() {
        if (mTemplet != null) {
            mChildBoundRect.clear();
            int count = mTemplet.getCollageNumber();
            mCacheBitmap = null;
            float ratio = Ratio.SCALE_FACTOR[mType.ordinal()];
            if (mViewRect.width() / ratio <= mViewRect.height()) {//要缩放高
                mAllChildRect.left = 0;
                mAllChildRect.top = (mViewRect.height() - mViewRect.width() / ratio) / 2;
                mAllChildRect.right = mViewRect.width();
                mAllChildRect.bottom = mAllChildRect.top + mViewRect.width() / ratio;
            } else {
                mAllChildRect.left = (mViewRect.width() - mViewRect.height() * ratio) / 2;
                mAllChildRect.top = 0;
                mAllChildRect.right = mAllChildRect.left + mViewRect.height() * ratio;
                mAllChildRect.bottom = mViewRect.height();
            }
            for (int i = 0; i < count; i++) {
                if (!(getChildAt(i) instanceof ICollagePathView)) {
                    continue;
                }
                CollagePoints collage = mTemplet.getCollagePoints(i);
                IStatus preAttr = mTemplet.getPreStatus(i);
                RectF boundRect = collage.getBoundRect();
                RectF childRect = new RectF(mAllChildRect.left + boundRect.left * mAllChildRect.width(), mAllChildRect.top + boundRect.top * mAllChildRect.height(),
                        mAllChildRect.left + boundRect.right * mAllChildRect.width(), mAllChildRect.top + boundRect.bottom * mAllChildRect.height());

                checkRectF(childRect);
                mChildBoundRect.add(childRect);

                ICollagePathView pathView = (ICollagePathView) getChildAt(i);
                LayoutParams lp = (LayoutParams) ((View) pathView).getLayoutParams();
                if (mDistanceProgress == 0) {
                    RoundPathUtil.getFitPath(pathView.getPath(), collage, mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
                    RectF current = new RectF(childRect);

                    lp.width = (int) current.width();
                    lp.height = (int) current.height();
                    lp.topMargin = (int) current.top;
                    lp.leftMargin = (int) current.left;

                    pathView.setData(childRect, pathView.getPath(), current, mAllChildRect, collage, preAttr);
                    ((View) pathView).setLayoutParams(lp);
                } else {
                    RoundPathUtil.getFitPath(pathView.getPath(), collage, mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
                    RectF pathBound = new RectF();
                    pathView.getPath().computeBounds(pathBound, false);
                    RectF current = new RectF(pathBound);
                    current.offset(mAllChildRect.left, mAllChildRect.top);

                    int width = (int) Math.ceil(current.width());
                    int height = (int) Math.ceil(current.height());
                    int left = (int) current.left;
                    int top = (int) current.top;
                    if (width + left < current.right) {
                        width += 1;
                    }
                    if (height + top < current.bottom) {
                        height += 1;
                    }
                    lp.width = width;
                    lp.height = height;
                    lp.topMargin = top;
                    lp.leftMargin = left;

                    current.set(left, top, width + left, height + top);
                    pathView.setData(childRect, pathView.getPath(), current, mAllChildRect, collage, preAttr);
                    ((View) pathView).setLayoutParams(lp);
                }
            }
            if (mDragPointView != null) {
                LayoutParams lp = new LayoutParams((int) mAllChildRect.width(), (int) mAllChildRect.height());
                lp.topMargin = (int) mAllChildRect.top;
                lp.leftMargin = (int) mAllChildRect.left;
                mDragPointView.setLayoutParams(lp);
            }
            invalidate();
        }
    }


    /**
     * 刷新当前边距
     */
    public void invalidateChildViewSize() {
        if (mDistanceProgress == 0) {// 它为0时 由于getDefaultRect已经进行了checkRectF所以不需要在将宽高减少误差
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                if (!(getChildAt(i) instanceof ICollagePathView)) {
                    continue;
                }
                ICollagePathView pathView = (ICollagePathView) getChildAt(i);
                RectF current = new RectF(pathView.getDefaultRect());

                LayoutParams lp = (LayoutParams) ((View) pathView).getLayoutParams();
                lp.width = (int) current.width();
                lp.height = (int) current.height();
                lp.topMargin = (int) current.top;
                lp.leftMargin = (int) current.left;

                pathView.setCurrentRect(current, mAllChildRect);
                CollagePoints points = pathView.getCollage();
                IStatus preAttr = mTemplet.getPreStatus(i);
                pathView.updateData(current, pathView.getPath()
                        , new RectF(current), mAllChildRect, points, preAttr);
                ((View) pathView).setLayoutParams(lp);

                RoundPathUtil.getFitPath(pathView.getPath(), points, mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
                pathView.setPath(pathView.getPath());

                pathView.refresh();
            }
        } else {
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                if (!(getChildAt(i) instanceof ICollagePathView)) {
                    continue;
                }
                final ICollagePathView pathView = (ICollagePathView) getChildAt(i);

                CollagePoints points = pathView.getCollage();

                RoundPathUtil.getFitPath(pathView.getPath(), points, mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
                pathView.setPath(pathView.getPath());

                RectF pathBound = new RectF();
                pathView.getPath().computeBounds(pathBound, false);

                RectF current = new RectF(pathBound);
                current.offset(mAllChildRect.left, mAllChildRect.top);

                int width = (int) Math.ceil(current.width());
                int height = (int) Math.ceil(current.height());
                int left = (int) current.left;
                int top = (int) current.top;
                if (width + left < current.right) {
                    width += 1;
                }
                if (height + top < current.bottom) {
                    height += 1;
                }
                LayoutParams lp = (LayoutParams) ((View) pathView).getLayoutParams();
                lp.width = width;
                lp.height = height;
                lp.topMargin = top;
                lp.leftMargin = left;

                current.set(left, top, width + left, height + top);
                pathView.setCurrentRect(current, mAllChildRect);
                IStatus preAttr = mTemplet.getPreStatus(i);
                pathView.updateData(current, pathView.getPath()
                        , new RectF(current), mAllChildRect, points, preAttr);
                ((View) pathView).setLayoutParams(lp);
                pathView.refresh();
            }
        }
    }

    public void invalidatePath() {
        if (mDistanceProgress == 0) {// 它为0时 由于getDefaultRect已经进行了checkRectF所以不需要在将宽高减少误差
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                if (!(getChildAt(i) instanceof ICollagePathView)) {
                    continue;
                }
                ICollagePathView pathView = (ICollagePathView) getChildAt(i);
                CollagePoints points = pathView.getCollage();
                RectF boundRect = points.getBoundRect();
                RectF childRect = new RectF(mAllChildRect.left + boundRect.left * mAllChildRect.width(), mAllChildRect.top + boundRect.top * mAllChildRect.height(),
                        mAllChildRect.left + boundRect.right * mAllChildRect.width(), mAllChildRect.top + boundRect.bottom * mAllChildRect.height());
                checkRectF(childRect);

                LayoutParams lp = (LayoutParams) ((View) pathView).getLayoutParams();
                lp.width = (int) childRect.width();
                lp.height = (int) childRect.height();
                lp.topMargin = (int) childRect.top;
                lp.leftMargin = (int) childRect.left;

                pathView.setCurrentRect(childRect, mAllChildRect);
                IStatus preAttr = mTemplet.getPreStatus(i);
                pathView.updateData(childRect, pathView.getPath()
                        , new RectF(childRect), mAllChildRect, points, preAttr);
                ((View) pathView).setLayoutParams(lp);

                RoundPathUtil.getFitPath(pathView.getPath(), points, mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
                pathView.setPath(pathView.getPath());

                pathView.refresh();
            }
        } else {
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                if (!(getChildAt(i) instanceof ICollagePathView)) {
                    continue;
                }
                final ICollagePathView pathView = (ICollagePathView) getChildAt(i);

                CollagePoints points = pathView.getCollage();

                RoundPathUtil.getFitPath(pathView.getPath(), points, mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
                pathView.setPath(pathView.getPath());

                RectF pathBound = new RectF();
                pathView.getPath().computeBounds(pathBound, false);

                RectF current = new RectF(pathBound);
                current.offset(mAllChildRect.left, mAllChildRect.top);

                int width = (int) Math.ceil(current.width());
                int height = (int) Math.ceil(current.height());
                int left = (int) current.left;
                int top = (int) current.top;
                if (width + left < current.right) {
                    width += 1;
                }
                if (height + top < current.bottom) {
                    height += 1;
                }
                LayoutParams lp = (LayoutParams) ((View) pathView).getLayoutParams();
                lp.width = width;
                lp.height = height;
                lp.topMargin = top;
                lp.leftMargin = left;

                current.set(left, top, width + left, height + top);
                pathView.setCurrentRect(current, mAllChildRect);
                IStatus preAttr = mTemplet.getPreStatus(i);
                pathView.updateData(current, pathView.getPath()
                        , new RectF(current), mAllChildRect, points, preAttr);
                ((View) pathView).setLayoutParams(lp);
                pathView.refresh();
            }
        }
    }

    public void resetChildViewBound() {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            final ICollagePathView pathView = (ICollagePathView) getChildAt(i);
            pathView.resetBound();
        }
    }

    /**
     * 更换模板后刷新所有的子View
     */
    public void initAllChildView() {
        if (mTemplet != null) {
            mChildBoundRect.clear();
            int count = mTemplet.getCollageNumber();
            for (int i = 0; i < count; i++) {
                if (!(getChildAt(i) instanceof ICollagePathView)) {
                    continue;
                }
                CollagePoints collage = mTemplet.getCollagePoints(i);
                IStatus preAttr = mTemplet.getPreStatus(i);
                RectF boundRect = collage.getBoundRect();
                RectF childRect = new RectF(mAllChildRect.left + boundRect.left * mAllChildRect.width(), mAllChildRect.top + boundRect.top * mAllChildRect.height(),
                        mAllChildRect.left + boundRect.right * mAllChildRect.width(), mAllChildRect.top + boundRect.bottom * mAllChildRect.height());

                checkRectF(childRect);
                mChildBoundRect.add(childRect);

                ICollagePathView pathView = (ICollagePathView) getChildAt(i);
                LayoutParams lp = (LayoutParams) ((View) pathView).getLayoutParams();
                if (mDistanceProgress == 0) {
                    RoundPathUtil.getFitPath(pathView.getPath(), collage, mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
                    RectF current = new RectF(childRect);

                    lp.width = (int) current.width();
                    lp.height = (int) current.height();
                    lp.topMargin = (int) current.top;
                    lp.leftMargin = (int) current.left;

                    pathView.setData(childRect, pathView.getPath()
                            , current, mAllChildRect, collage, preAttr);
                    ((View) pathView).setLayoutParams(lp);
                } else {
                    RoundPathUtil.getFitPath(pathView.getPath(), collage, mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
                    RectF pathBound = new RectF();
                    pathView.getPath().computeBounds(pathBound, false);

                    RectF current = new RectF(pathBound);
                    current.offset(mAllChildRect.left, mAllChildRect.top);

                    int width = (int) Math.ceil(current.width());
                    int height = (int) Math.ceil(current.height());
                    int left = (int) current.left;
                    int top = (int) current.top;
                    if (width + left < current.right) {
                        width += 1;
                    }
                    if (height + top < current.bottom) {
                        height += 1;
                    }
                    lp.width = width;
                    lp.height = height;
                    lp.topMargin = top;
                    lp.leftMargin = left;

                    current.set(left, top, width + left, height + top);

                    pathView.setData(childRect, pathView.getPath(), current, mAllChildRect, collage, preAttr);
                    ((View) pathView).setLayoutParams(lp);
                }
            }
            invalidate();
        }
    }

    /**
     * 调整圆角时候的刷新
     */
    public void invalidateRound() {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            ICollagePathView pathView = (ICollagePathView) getChildAt(i);
            if (pathView instanceof CollageVideoView) {
                continue;
            }
            RoundPathUtil.getFitPath(pathView.getPath(), pathView.getCollage(), mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
            pathView.setPath(pathView.getPath());
            pathView.refresh();
        }
    }

    /**
     * 设置背景
     *
     * @param bitmap
     */
    public void setBgBitmap(Bitmap bitmap, BitmapBean bitmapBean, boolean fitViewSize) {
        mBgBitmap = bitmap;
        if (mBgBitmap != null && !mBgBitmap.isRecycled()) {
            mBgPaint.setShader(null);
            BitmapShader shader = new BitmapShader(mBgBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
            if (fitViewSize && getWidth() != 0 && getHeight() != 0) {
                float scale = (float) Math.max(getHeight() * 1.0 / mBgBitmap.getHeight(), getWidth() * 1.0 / mBgBitmap.getWidth());
                float xOffset = (mBgBitmap.getWidth() * scale - getWidth()) / 2;
                float yOffset = (mBgBitmap.getHeight() * scale - getHeight()) / 2;
                Matrix matrix = new Matrix();
                matrix.postScale(scale, scale);
                matrix.postTranslate(-xOffset, -yOffset);
                shader.setLocalMatrix(matrix);
            }
            mBgPaint.setShader(shader);
            mIsColorBg = false;
        } else {
            stopPlayGif();
            mBgPaint.setShader(null);
            //复原
            mBgColor = Color.WHITE;
            mColorBgPaint.setColor(mBgColor);
            mIsColorBg = true;
        }
        mBgBitmapBean = bitmapBean;
        if (mGifBitmap != null && !mGifBitmap.isRecycled()) {
            mGifBitmap.recycle();
            mGifBitmap = null;
        }
        if (mGifBitmapForRender != null && !mGifBitmapForRender.isRecycled()) {
            mGifBitmapForRender.recycle();
            mGifBitmapForRender = null;
        }
        startPlayGif();
        mUseBg = true;
        invalidate();
    }

    public void stopPlayGif() {
        if (mGifBitmap != null) {
            mGifBitmap.setOnGifRefreshListener(null);
            mGifBitmap.stop();
        }
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View view = getChildAt(i);
//            if (view != null
//                    && view instanceof CollagePathView) {
//                ((CollagePathView) view).stopPlayGif();
//            }
        }
    }

    public void startPlayGif() {
        stopPlayGif();
        if (mBgBitmapBean != null && mBgBitmapBean.mType == MediaTypeUtil.TYPE_GIF) {
            try {
                mGifBitmap = new GifBitmap(mBgBitmapBean.mPath);
                mGifBitmapForRender = new GifBitmap(mBgBitmapBean.mPath);
                mGifBitmap.setOnGifRefreshListener(this);
                mGifBitmap.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View view = getChildAt(i);
//            if (view != null
//                    && view instanceof CollagePathView) {
//                ((CollagePathView) view).startPlayGif();
//            }
        }
    }

    public boolean containGif() {
        boolean containGifBg = mBgBitmapBean != null && mBgBitmapBean.mType == MediaTypeUtil.TYPE_GIF;
        if (containGifBg) {
            return true;
        }
        boolean containGifChild = false;
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View view = getChildAt(i);
//            if (view != null
//                    && view instanceof CollagePathView
//                    && ((CollagePathView) view).getBitmapBean() != null
//                    && ((CollagePathView) view).getBitmapBean().mType == MediaTypeUtil.TYPE_GIF) {
//                containGifChild = true;
//                break;
//            }
        }
        return containGifChild;
    }

    public int getGifDuration() {
        if (!containGif()) {
            return 0;
        }
        int duration = mGifBitmap == null ? 0 : mGifBitmap.getDuration();
        int count = getChildCount();
//        for(int i = 0 ; i < count ; i++){
//            View view = getChildAt(i);
//            if (view != null
//                    && view instanceof CollagePathView
//                    && ((CollagePathView) view).isGif()
//                    && ((CollagePathView) view).getGifDuration() > duration) {
//                duration = ((CollagePathView) view).getGifDuration();
//            }
//        }
        if (duration > 0) {
            while (duration < 1000) {
                duration *= 2;
            }
        }
        return duration;
    }


    /**
     * gif图片刷新
     *
     * @param bitmap
     */
    @Override
    public void onRefresh(Bitmap bitmap) {
        BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
        mBgPaint.setShader(shader);
        postInvalidate();
    }

    /**
     * 设置背景 设置图片的Id
     *
     * @param id
     */
    public void setBgResource(int id) {
        setBgDrawable(getResources().getDrawable(id));
    }

    /**
     * 设置背景
     *
     * @param d
     */
    public void setBgDrawable(Drawable d) {
        stopPlayGif();
        if (d instanceof BitmapDrawable) {
            setBgBitmap(((BitmapDrawable) d).getBitmap(), null, false);
        } else if (d instanceof ColorDrawable) {
            ColorDrawable colorDrawable = (ColorDrawable) d;
            int color = colorDrawable.getColor();
            setBgColor(color);
        } else {
            Bitmap bitmap = Bitmap.createBitmap(d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
            d.draw(canvas);
            setBgBitmap(bitmap, null, false);
        }
    }

    /**
     * 设置背景颜色
     *
     * @param color
     */
    public void setBgColor(int color) {
        stopPlayGif();
        mBgBitmapBean = null;
        mIsColorBg = true;
        mBgColor = color;
        mColorBgPaint.setColor(mBgColor);
        mUseBg = color != Color.WHITE;
        invalidate();
    }

    public Rect getOutputSize() {
        return getOutputSize(false);
    }

    /**
     * 获取输出内容的宽高
     *
     * @return
     */
    public Rect getOutputSize(boolean forGif) {
        int width;
        int height;
        float ratio = Ratio.SCALE_FACTOR[mType.ordinal()];
        if (hasVideoorGif() && !mFromMirror) {
            if (Gif2VideoUtils.sSuppoft1080) {
                height = Gif2VideoUtils.VIDEO_OUTPUT_H;
                width = (int) (height * ratio + 0.5f);
                width = MediaCodecHelper.getInstance().getSupportVideoWidth(width, height);
            } else {
                width = Gif2VideoUtils.VIDEO_OUTPUT_H;
                height = (int) (width / ratio);
                height = MediaCodecHelper.getInstance().getSupportVideoHeight(width, height);
            }
        } else {
            width = getCollageBitmapWidth(ratio);
            height = (int) (width / ratio + 0.5f);
            float scale = ImageHelper.checkCanvasAndTextureSizeHalf(width, height, 1);
            if (scale != 1) {
                width /= scale;
                height /= scale;
            }
            if (forGif) {
                int[] size = Gif2VideoUtils.getVideoOutputSize(width, height);
                width = size[0];
                height = size[1];
            }
        }
        return new Rect(0, 0, width, height);
    }

    /**
     * 合成成真正的图片
     * 遍历所有的子View  然后获取其Path 和源图片 绘制在画板上
     *
     * @return
     */
    public Bitmap getCollageBitmap() {
        return getCollageBitmap(0);
    }

    public Bitmap getCollageBitmap(boolean ignoreVideo) {
        return getCollageBitmap(0, ignoreVideo);
    }

    public Bitmap getCollageBitmap(long timestamp) {
        return getCollageBitmap(timestamp, false);
    }

    public Bitmap getCollageBitmap(long timestamp, boolean ignoreVideo) {
        Rect size;
        size = getOutputSize();
        int width = size.width();
        int height = size.height();
        float currentWidth = mAllChildRect.width();
        float currentHeight = mAllChildRect.height();

        if (mCacheBitmap == null) {
            mCacheBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        }
        Paint bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        bitmapPaint.setStyle(Paint.Style.FILL);
        bitmapPaint.setColor(mBgColor);

        Canvas canvas = new Canvas(mCacheBitmap);
        if (mIsColorBg) {
            canvas.drawColor(mBgColor);
        } else {
            //白底
            canvas.drawColor(Color.WHITE);
            if (mGifBitmapForRender != null) {
                mBgPaint.setShader(new BitmapShader(
                        mGifBitmapForRender.seekToPositionAndGet((int) (timestamp % mGifBitmapForRender.getDuration())),
                        Shader.TileMode.REPEAT,
                        Shader.TileMode.REPEAT));
            }
            //这样处理是为了防止生成后的背景和原来的背景对不上
            int saveCount = canvas.save();
            canvas.scale(width / currentWidth, height / currentHeight);
            // 使用图片背景时需要加上偏移量，因为预览时默认是从View的顶部开始画的，而实际显示的是mAllChildRect区域
            canvas.translate(-mAllChildRect.left, -mAllChildRect.top);
            canvas.drawRect(new RectF(0, 0, currentWidth + mAllChildRect.left, currentHeight + mAllChildRect.top), mBgPaint);
            canvas.restoreToCount(saveCount);
        }

        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            ICollagePathView pathView = (ICollagePathView) getChildAt(i);
            if (ignoreVideo && pathView instanceof CollageVideoView) {
                continue;
            }
            int saveCount1 = canvas.saveLayer(0.0f, 0.0f, width, height,
                    null, Canvas.ALL_SAVE_FLAG);
            int saveCount2 = canvas.save();
            canvas.scale(width / currentWidth, height / currentHeight);
            canvas.clipPath(pathView.getPath());
            if (pathView instanceof CollageVideoView) {
                Rect rect = pathView.getRegion().getBounds();
                rect.left += 1;
                rect.top += 1;
                rect.right -= 1;
                rect.bottom -= 1;
                canvas.clipRect(rect);
            }
            canvas.translate(-pathView.getTranslateX(), -pathView.getTranslateY());
            Bitmap bitmap = pathView.getSourceBitmap(timestamp);
            if (bitmap != null && !bitmap.isRecycled()) {
                canvas.drawBitmap(bitmap, pathView.getDrawMatrix(), bitmapPaint);
            }
            canvas.restoreToCount(saveCount2);
            canvas.restoreToCount(saveCount1);
        }
        if (timestamp == 0) {
            // 用于外部使用,防止外部更改位图
            return mCacheBitmap.copy(Bitmap.Config.ARGB_8888, true);
        }
        // 合成gif时使用
        return mCacheBitmap;
    }

    public Bitmap getCollageColorBg() {
        Rect size = getOutputSize();
        int width = size.width();
        int height = size.height();

        if (mCacheBitmap == null) {
            mCacheBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        }
        Paint bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        bitmapPaint.setStyle(Paint.Style.FILL);
        bitmapPaint.setColor(mBgColor);

        Canvas canvas = new Canvas(mCacheBitmap);
        if (mIsColorBg) {
            canvas.drawColor(mBgColor);
        }
        return mCacheBitmap;
    }

    /**
     * 获取当前图片应有的宽高
     *
     * @param ratio
     * @return
     */
    public int getCollageBitmapWidth(float ratio) {
        float maxSize = ImageHelper.getCurrentMaxSize() / 4;
        return (int) Math.sqrt(maxSize * ratio);
    }

    public RectF getViewRect() {
        return new RectF(mViewRect);
    }

    public RectF getAllChildRect() {
        return new RectF(mAllChildRect);
    }

    /**
     * 一下是处理相关的事件
     */

    //当前操作的View
    private ICollagePathView mCurrentOperationView;

    //当前需要修改Bitmoa的View
    private ICollagePathView mChangeBitmapView;
    private final int SELECTED_NONE = 0;
    private final int SELECTED_AND_MOVE = 1;
    private final int SELECTED_AND_SCALE = 2;
    private final int SELECTED_AND_CHANGE = 3;
    private final int SELECTED_AND_EDIT = 4;
    private final int SELECTED_AND_CHANGE_SIMPLE = 5; // 点击直接替换模式
    private int mTouchMode = SELECTED_NONE;

    boolean mInFilterMode = false;
    //滤镜模式不刷新layout
    boolean mIsFilter = false;

    private CollageGestureRecognizer mGestureRecognizer;

    private void dealSelectMove(float x, float y) {
        float trueX = x - mAllChildRect.left;
        float trueY = y - mAllChildRect.top;
        int count = getChildCount();
        for (int i = count - 1; i >= 0; i--) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            ICollagePathView view = (ICollagePathView) getChildAt(i);
            Region region = view.getRegion();
            if (region.contains((int) trueX, (int) trueY)) {
                mCurrentOperationView = view;
                if (getMode() == MODE_COLLAGE) {
                    mCurrentOperationView.setIsTouch(true);
                }
                mTouchMode = SELECTED_AND_MOVE;
                return;
            }
        }
        mTouchMode = SELECTED_NONE;
    }

    /**
     * 两个手指的时候执行
     *
     * @param event
     */
    private void dealSelectScale(MotionEvent event) {
        float x1 = event.getX(0);
        float y1 = event.getY(0);

        float x2 = event.getX(1);
        float y2 = event.getY(1);

        float centerX = (x1 + x2) / 2 - mAllChildRect.left;
        float centerY = (y1 + y2) / 2 - mAllChildRect.top;

        int count = getChildCount();
        for (int i = count - 1; i >= 0; i--) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            ICollagePathView view = (ICollagePathView) getChildAt(i);
            Region region = view.getRegion();
            if (region.contains((int) centerX, (int) centerY)) {
                if (mOnOperationListener != null) {
                    mOnOperationListener.onCollageOperation(true);
                }
                if (mCurrentOperationView == view) {
                    mCurrentOperationView.setIsTouch(true);
                    mTouchMode = SELECTED_AND_SCALE;
                    return;
                } else {
                    if (mCurrentOperationView != null) {
                        mCurrentOperationView.setIsTouch(false);
                    }
                    int index = event.getActionIndex();
                    float x = event.getX(1 - index);
                    float y = event.getY(1 - index);
                    dealSelectUp(mCurrentOperationView, x, y);
                    mCurrentOperationView = view;
                    mCurrentOperationView.setIsTouch(true);
                    mTouchMode = SELECTED_AND_SCALE;
                    return;
                }
            }
        }
        mTouchMode = SELECTED_NONE;
    }

    private void dealSelectUp(ICollagePathView view, float x, float y) {
        if (view != null) {//用于处理缩小的过小的时候
            RectF rectF = view.getCurrentRect();
            float trueX = x - rectF.left;
            float trueY = y - rectF.top;
            view.onUp(trueX, trueY);
        }
    }

    /**
     * 处理长按
     *
     * @param x
     * @param y
     */
    private void dealLongPress(float x, float y) {
        //trueX trueY
        float trueX = x - mAllChildRect.left;
        float trueY = y - mAllChildRect.top;
        int count = getChildCount();
        for (int i = count - 1; i >= 0; i--) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            ICollagePathView view = (ICollagePathView) getChildAt(i);
            Region region = view.getRegion();
            if (region.contains((int) trueX, (int) trueY)) {
                mCurrentOperationView = view;
                mCurrentOperationView.setIsInChange(true);
                mCurrentOperationView.setIsTouch(true);
                mCollage.showCollageCover(view, x, y);
                view.onLongPress(x, y);
                mTouchMode = SELECTED_AND_CHANGE;
                return;
            }
        }
        mTouchMode = SELECTED_NONE;
    }

    /**
     * 处理点击
     *
     * @param x
     * @param y
     */
    private void dealTapConfirm(float x, float y) {
        if (mTouchMode == SELECTED_AND_CHANGE_SIMPLE) {
            return;
        }
        //trueX trueY
        float trueX = x - mAllChildRect.left;
        float trueY = y - mAllChildRect.top;
        int count = getChildCount();
        mTouchMode = SELECTED_NONE;
        for (int i = count - 1; i >= 0; i--) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            ICollagePathView view = (ICollagePathView) getChildAt(i);
            Region region = view.getRegion();
            if (region.contains((int) trueX, (int) trueY) && mTouchMode == SELECTED_NONE) {
                mCurrentOperationView = view;
                mCurrentOperationView.setIsTouch(true);
                mTouchMode = SELECTED_AND_EDIT;

                enableDragRegionMode();
            } else {
                view.setIsTouch(false);
            }
        }
    }

    private void changeFocus(float x, float y) {
        if (mTouchMode == SELECTED_AND_CHANGE_SIMPLE) {
            return;
        }
        //trueX trueY
        float trueX = x - mAllChildRect.left;
        float trueY = y - mAllChildRect.top;
        int count = getChildCount();
        for (int i = count - 1; i >= 0; i--) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            ICollagePathView view = (ICollagePathView) getChildAt(i);
            Region region = view.getRegion();
            if (region.contains((int) trueX, (int) trueY)) {
                mCurrentOperationView = view;
                mCurrentOperationView.setIsTouch(true);
            } else {
                view.setIsTouch(false);
            }
        }
    }

    public void enableSimpleChangeMode() {
        if (mCurrentOperationView != null) {
            mCurrentOperationView.setIsTouch(true);
            mTouchMode = SELECTED_AND_CHANGE_SIMPLE;
            disableDragMode();
        }
    }

    public void enableDragRegionMode() {
        if (mCurrentOperationView != null) {
            mCurrentOperationView.setIsTouch(true);
//            mTouchMode = SELECTED_AND_DRAG_REGION;
            mDragPointList = mTemplet.getDragPointList(mCurrentOperationView.getCollage(),
                    mAllChildRect.width(), mAllChildRect.height(), mDistanceProgress);
            mDragPointListNoDistance = mTemplet.getDragPointList(mCurrentOperationView.getCollage(),
                    mAllChildRect.width(), mAllChildRect.height(), 0);
            if (mDragPointView != null) {
                mDragPointView.setVisibility(VISIBLE);
                mDragPointView.setDragPointList(mDragPointList);
            }
            invalidate();
        }
    }

    public void disableDragMode() {
//        mTouchMode = SELECTED_NONE;
        mIsInDrag = false;
        mDragPointView.setVisibility(INVISIBLE);
    }

    private boolean mTouchAble = true;

    public void setTouchAble(boolean touchAble) {
        mTouchAble = touchAble;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {//分发Touch事件
        if (!mTouchAble) {
            return false;
        }
        if (mIsList) return super.onTouchEvent(event);
        if (!mIsInit || mInFilterMode) return true;//拦截掉
        int count = event.getPointerCount();
        int parentX = (int) (event.getX() - mAllChildRect.left);
        int parentY = (int) (event.getY() - mAllChildRect.top);
        switch (event.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN:
                if (mTouchMode == SELECTED_AND_CHANGE_SIMPLE && mCurrentOperationView != null) {
                    int childCount = getChildCount();
                    for (int i = 0; i < childCount; i++) {
                        if (!(getChildAt(i) instanceof ICollagePathView)) {
                            continue;
                        }
                        ICollagePathView view = (ICollagePathView) getChildAt(i);
                        Region region = view.getRegion();
                        if (mCurrentOperationView != view) {
                            if (region.contains(parentX, parentY)) {
                                view.setIsTouch(true);
                                mChangeBitmapView = view;
                                if (mOnOperationListener != null) {
                                    mOnOperationListener.onCollageOperation(true);
                                }
                            } else {
                                view.setIsTouch(false);
                                if (mOnOperationListener != null) {
                                    mOnOperationListener.onCollageOperation(false);
                                }
                            }
                        }
                    }
                } else {
                    if (mTouchMode == SELECTED_AND_EDIT && mDragPointView != null) {
                        int collageNumber = mTemplet.getCollageNumber();
                        Point touchPoint = new Point(parentX, parentY);
                        com.photoeditor.demo.model.image.collage.templet.Point touchOffset = new com.photoeditor.demo.model.image.collage.templet.Point();
                        int index = mDragPointView.getTouchOffset(touchPoint, touchOffset);
                        if (index != -1) {
                            if (mOnOperationListener != null) {
                                mOnOperationListener.onCollageOperation(true);
                            }
                            mIsInDrag = true;
                            DragPoint noDistancePoint = mDragPointListNoDistance.get(index);
                            DragPoint distancePoint = mDragPointList.get(index);
                            touchOffset.offset(noDistancePoint.x - distancePoint.x, noDistancePoint.y - distancePoint.y);
                            for (int i = 0; i < collageNumber; i++) {
                                CollagePoints collagePoints = mTemplet.getCollagePoints(i);
                                collagePoints.startDrag(touchPoint, touchOffset, noDistancePoint.orientation, mAllChildRect.width(), mAllChildRect.height());
                            }
                        } else {
                            mIsInDrag = false;
                            if (mOnOperationListener != null) {
                                mOnOperationListener.onCollageOperation(false);
                            }
                        }
                    } else {
                        if (count == 1) {
                            if (mOnOperationListener != null) {
                                mOnOperationListener.onCollageOperation(true);
                            }
                            dealSelectMove(event.getX(), event.getY());
                        } else {
                            mTouchMode = SELECTED_NONE;
                            if (mOnOperationListener != null) {
                                mOnOperationListener.onCollageOperation(false);
                            }
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (mIsInDrag) {
                    Point touchPoint = new Point(parentX, parentY);
                    int collageNumber = mTemplet.getCollageNumber();
                    boolean shouldRollBack = false;
                    for (int i = 0; i < collageNumber; i++) {
                        CollagePoints collagePoints = mTemplet.getCollagePoints(i);
                        shouldRollBack |= collagePoints.updateMovingPoint(touchPoint, mAllChildRect.width(), mAllChildRect.height());
                    }
                    if (shouldRollBack) {
                        for (int i = 0; i < collageNumber; i++) {
                            CollagePoints collagePoints = mTemplet.getCollagePoints(i);
                            collagePoints.rollBackUpdatePoint();
                        }
                    }
                    mDragPointList = mTemplet.getDragPointList(mCurrentOperationView.getCollage(),
                            mAllChildRect.width(), mAllChildRect.height(), mDistanceProgress);
                    mDragPointListNoDistance = mTemplet.getDragPointList(mCurrentOperationView.getCollage(),
                            mAllChildRect.width(), mAllChildRect.height(), 0);
                    if (mDragPointView != null) {
                        mDragPointView.setDragPointList(mDragPointList);
                    }
                    invalidatePath();
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                if (getMode() == MODE_COLLAGE) {
                    if (mTouchMode != SELECTED_AND_EDIT && mTouchMode != SELECTED_AND_CHANGE) {
                        if (count == 2) {
                            dealSelectScale(event);
                        } else {
                            mTouchMode = SELECTED_NONE;
                        }
                    }
                } else if (getMode() == MODE_MIRROR) {
                    //do nothing
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (mIsInDrag) {
                    mIsInDrag = false;
                    int collageNumber = mTemplet.getCollageNumber();
                    for (int i = 0; i < collageNumber; i++) {
                        CollagePoints collagePoints = mTemplet.getCollagePoints(i);
                        collagePoints.stopDrag();
                    }
                } else {
                    if (getMode() == MODE_COLLAGE) {
                        if (mTouchMode == SELECTED_AND_EDIT) {
                            cancelSelectEdit();
                        }
                    } else if (getMode() == MODE_MIRROR) {
                        //do nothing
                    }
                }
                if (mOnOperationListener != null) {
                    mOnOperationListener.onCollageOperation(false);
                }
                break;
        }
        if (mTouchMode != SELECTED_AND_EDIT) {
            mGestureRecognizer.onTouchEvent(event);
        }
        return true;
    }

    @Override
    public boolean onSingleTapUp(float x, float y) {
        if (getMode() == MODE_COLLAGE) {
            if (mTouchMode != SELECTED_AND_SCALE && mTouchMode != SELECTED_AND_CHANGE_SIMPLE) {
                dealTapConfirm(x, y);
                if (mTouchMode == SELECTED_AND_EDIT && mCurrentOperationView != null) {
                    mCollage.showPopView(mCurrentOperationView);
                } else {
                    mCollage.closePopView();
                }
            }
        } else if (getMode() == MODE_MIRROR) {
            //do nothing
        }
        return true;
    }

    @Override
    public boolean onSingleTapComfirm(float x, float y) {
        return true;
    }

    @Override
    public boolean onDoubleTap(float x, float y) {
        return false;
    }

    @Override
    public boolean onScroll(float x, float y, float dx, float dy, float totalX, float totalY) {
        if (mCurrentOperationView == null) return true;
        if (getMode() == MODE_COLLAGE) {
            if (mTouchMode == SELECTED_AND_MOVE) {
                int parentX = (int) (x - mAllChildRect.left);
                int parentY = (int) (y - mAllChildRect.top);

                RectF rectF = mCurrentOperationView.getCurrentRect();
                float trueX = x - rectF.left;
                float trueY = y - rectF.top;
                mCurrentOperationView.onScroll(trueX, trueY, dx, dy, totalX, totalY);

                float data[] = new float[2];
                if (mCurrentOperationView.isNeedEnsureRect(data)) {
                    boolean isChangeMode = false;
                    boolean isDontChange = false;
                    int count = getChildCount();
                    for (int i = count - 1; i >= 0; i--) {
                        if (!(getChildAt(i) instanceof ICollagePathView)) {
                            continue;
                        }
                        ICollagePathView view = (ICollagePathView) getChildAt(i);
                        Region region = view.getRegion();
                        if (mCurrentOperationView != view) {
                            if (region.contains(parentX, parentY) && !isChangeMode && !isDontChange) {
                                isChangeMode = true;
                                view.setIsTouch(true);
                                mChangeBitmapView = view;
                            } else {
                                view.setIsTouch(false);
                            }
                        } else {
                            if (!isChangeMode) {
                                if (mCurrentOperationView.getRegion().contains(parentX, parentY)) {//选中了当前的
                                    mCurrentOperationView.setIsTouch(true);
                                    isDontChange = true;
                                }
                            } else {

                            }
                        }
                    }

                    if (!isChangeMode && !isDontChange) {//什么也没选中
                        mCurrentOperationView.setIsTouch(false);
                        mTouchMode = SELECTED_AND_CHANGE;
                        mCollage.showMoveCover(mCurrentOperationView, x, y, data[0], data[1]);
                        mCurrentOperationView.setIsInChange(true);
                    } else if (isChangeMode) {
                        mCurrentOperationView.setIsTouch(false);
                        mTouchMode = SELECTED_AND_CHANGE;
                        mCollage.showMoveCover(mCurrentOperationView, x, y, data[0], data[1]);
                        mCurrentOperationView.setIsInChange(true);
                    } else if (isDontChange) {
                        mCurrentOperationView.setIsTouch(true);
                    } else {
                        mCurrentOperationView.setIsTouch(false);
                    }
                } else if (mCurrentOperationView.getRegion().contains(parentX, parentY)) {
                    mCurrentOperationView.setIsTouch(true);
                    int count = getChildCount();
                    for (int i = 0; i < count; i++) {
                        if (!(getChildAt(i) instanceof ICollagePathView)) {
                            continue;
                        }
                        ICollagePathView view = (ICollagePathView) getChildAt(i);
                        if (view != mCurrentOperationView) {
                            view.setIsTouch(false);
                        }
                    }
                } else {
                    mCurrentOperationView.setIsTouch(false);
                }
            } else if (mTouchMode == SELECTED_AND_CHANGE) {
                mCollage.moveCollageCover(x, y);

                int parentX = (int) (x - mAllChildRect.left);
                int parentY = (int) (y - mAllChildRect.top);

                RectF rectF = mCurrentOperationView.getCurrentRect();
                float trueX = x - rectF.left;
                float trueY = y - rectF.top;
                mCurrentOperationView.onScroll(trueX, trueY, dx, dy, totalX, totalY);


                boolean isNeedChange = false;
                boolean isDontChange = false;
                int count = getChildCount();
                for (int i = count - 1; i >= 0; i--) {
                    if (!(getChildAt(i) instanceof ICollagePathView)) {
                        continue;
                    }
                    ICollagePathView view = (ICollagePathView) getChildAt(i);
                    Region region = view.getRegion();
                    if (mCurrentOperationView != view) {
                        if (region.contains(parentX, parentY) && !isNeedChange && !isDontChange) {
                            isNeedChange = true;
                            view.setIsTouch(true);
                            mChangeBitmapView = view;
                        } else {
                            view.setIsTouch(false);
                        }
                    } else {
                        if (isNeedChange) {//已经存在优先级更高的View  触发了更换图片的
                            mCurrentOperationView.setIsTouch(false);
                        } else {//不存在高优先级的 触发更换图片的
                            if (mCurrentOperationView.getRegion().contains(parentX, parentY)) {
                                mCurrentOperationView.setIsTouch(true);
                                isDontChange = true;
                            } else {
                                mCurrentOperationView.setIsTouch(false);
                            }
                        }
                    }
                }
            }
        } else if (getMode() == MODE_MIRROR) {
            if (mTouchMode == SELECTED_AND_MOVE) {
                float result[] = mCurrentOperationView.translateWidthoutPreAttr(-dx, -dy);
                if (isShareOperation()) {
                    int count = getChildCount();
                    for (int i = count - 1; i >= 0; i--) {
                        if (!(getChildAt(i) instanceof ICollagePathView)) {
                            continue;
                        }
                        ICollagePathView view = (ICollagePathView) getChildAt(i);
                        if (mCurrentOperationView != view) {
                            view.translateWidthPreAttr(result[0], result[1]);
                        }
                    }
                }
            }
        }
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        return true;
    }

    @Override
    public boolean onScaleBegin(float focusX, float focusY) {
        return true;
    }

    @Override
    public boolean onScale(float focusX, float focusY, float scale) {
        if (getMode() == MODE_COLLAGE) {
            if (mTouchMode == SELECTED_AND_SCALE && mCurrentOperationView != null) {
                RectF rectF = mCurrentOperationView.getCurrentRect();
                float trueFocusX = focusX - rectF.left;
                float trueFocusY = focusY - rectF.top;
                mCurrentOperationView.onScale(trueFocusX, trueFocusY, scale);
            }
        } else if (getMode() == MODE_MIRROR) {
            //do nothing
        }
        return true;
    }

    @Override
    public void onScaleEnd() {

    }

    @Override
    public boolean onRotaionBegin() {
        return true;
    }

    @Override
    public boolean onRotaion(float delta) {
        if (getMode() == MODE_COLLAGE) {
            if (mTouchMode == SELECTED_AND_SCALE && mCurrentOperationView != null) {
                mCurrentOperationView.onRotaion(delta);
            }
        }
        return true;
    }

    @Override
    public void onRotaionEnd() {

    }

    @Override
    public void onDown(float x, float y) {
    }

    @Override
    public void onUp(float x, float y) {
        if (getMode() == MODE_COLLAGE) {
            if (mTouchMode == SELECTED_AND_EDIT) {

            } else {
                mCollage.closePopView();
                boolean isStartGoneAnimation = false;
                if ((mTouchMode == SELECTED_AND_CHANGE && mCurrentOperationView != null
                        && mChangeBitmapView != null && mCurrentOperationView != mChangeBitmapView && mChangeBitmapView.isTouch()) ||
                        (mTouchMode == SELECTED_AND_CHANGE_SIMPLE && mChangeBitmapView != null)) {
                    BitmapBean changeBean = mChangeBitmapView.getBitmapBean();
                    BitmapBean operationBean = mCurrentOperationView.getBitmapBean();
                    if (changeBean.mType == MediaTypeUtil.TYPE_VIDEO || operationBean.mType == MediaTypeUtil.TYPE_VIDEO) {
                        mCurrentOperationView = null;
                        mChangeBitmapView = null;
                        mCollage.closeCollageCoverAndChangBitmap();
                        exchangeBean(changeBean, operationBean);
                        invalidateCollage();
                        mCollage.showLoading();
                        addOnLayoutChangeListener(new OnLayoutChangeListener() {
                            @Override
                            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                                mCollage.hideLoading();
                                removeOnLayoutChangeListener(this);
                            }
                        });
                        return;
                    }
                    exchangeBean(changeBean, operationBean);
                    Bitmap b = mChangeBitmapView.getSourceBitmap(0);
                    mChangeBitmapView.setSourceBitmap(mCurrentOperationView.getSourceBitmap(0));
                    mChangeBitmapView.setBitmapBean(mCurrentOperationView.getBitmapBean());
                    mChangeBitmapView = null;
                    mCurrentOperationView.setSourceBitmap(b);
                    mCurrentOperationView.setBitmapBean(changeBean);
                    mCollage.closeCollageCoverAndChangBitmap();
                    mCurrentOperationView.setIsInChange(false);
                } else {
                    if (mTouchMode == SELECTED_AND_CHANGE) {
                        mCollage.closeCollageCover();
                        isStartGoneAnimation = true;
                    }
                }
                int count = getChildCount();
                for (int i = 0; i < count; i++) {
                    if (!(getChildAt(i) instanceof ICollagePathView)) {
                        continue;
                    }
                    ICollagePathView view = (ICollagePathView) getChildAt(i);
                    view.setIsTouch(false);
                }
                dealSelectUp(mCurrentOperationView, x, y);
//                if (!isStartGoneAnimation) {
                mCurrentOperationView = null;
//                }
                mTouchMode = SELECTED_NONE;
            }
        } else if (getMode() == MODE_MIRROR) {
            mTouchMode = SELECTED_NONE;
        }
    }

    @Override
    public void onLongPress(float x, float y) {
        if (getMode() == MODE_COLLAGE) {
            if (mTouchMode != SELECTED_AND_SCALE) {
                dealLongPress(x, y);
            }
        } else if (getMode() == MODE_MIRROR) {
            //do nothing
        }
    }

    /**
     * Cover 的GONE动画完成后回调  让原图片显示
     */
    public void setAllViewNotInChange() {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            ICollagePathView view = (ICollagePathView) getChildAt(i);
            if (view.isInChange()) {
                view.setIsInChange(false);
            }
        }
    }

    /**
     * 旋转
     *
     * @param degree
     */
    public void rotation(int degree) {
        if (mCurrentOperationView != null) {
            mCurrentOperationView.rotation(degree);
        }
    }

    /**
     * 翻转
     *
     * @param horizontal
     */
    public void flip(boolean horizontal) {
        if (mCurrentOperationView != null) {
            mCurrentOperationView.flip(horizontal);
        }
    }

    /**
     * 更换图片后调用这个生效
     *
     * @param currentBitmap
     * @return
     */
    public int changeBitmap(Bitmap currentBitmap, BitmapBean bitmapBean) {
        int index = -1;
        if (mTouchMode == SELECTED_AND_EDIT && mCurrentOperationView != null && currentBitmap != null) {
            if (mIsSingeleBitmapMode || mSourceBitmaps.size() == 1) {//单张图片的模式不需要替换图片
                int childCount = getChildCount();
                for (int i = 0; i < childCount; i++) {
                    if (!(getChildAt(i) instanceof ICollagePathView)) {
                        continue;
                    }
                    ICollagePathView childAt = (ICollagePathView) getChildAt(i);
                    childAt.setSourceBitmap(currentBitmap);
                    childAt.setBitmapBean(bitmapBean);
                    mSourceBitmaps.set(0, currentBitmap);
                    mBitmapBeenList.set(0, bitmapBean);
                }
                //单张图片的模式下得对原图给换掉,并且两种模式下相互影响
                index = 0;
            } else {
                BitmapBean bean = mCurrentOperationView.getBitmapBean();
                index = mBitmapBeenList.indexOf(bean);
                mSourceBitmaps.set(index, currentBitmap);
                mBitmapBeenList.set(index, bitmapBean);
                if (mCurrentOperationView instanceof CollageVideoView) {
                    invalidateCollage();
                } else {
                    mCurrentOperationView.setSourceBitmap(currentBitmap);
                    mCurrentOperationView.setBitmapBean(bitmapBean);
                }
            }
            mCollage.closePopView();
            cancelSelectEdit();
        }
        return index;
    }

    /**
     * 滤镜界面确认后调用这个生效
     *
     * @param sourceBitmap
     * @param currentBitmap
     * @return
     */
    public int changeBitmap(Bitmap sourceBitmap, Bitmap currentBitmap) {
        int index = -1;
        mInFilterMode = false;
        if (mTouchMode == SELECTED_AND_EDIT && mCurrentOperationView != null && currentBitmap != null) {
            if (mIsSingeleBitmapMode) {//单张图片的模式不需要替换图片
                mCurrentOperationView.setFilterBitmap(currentBitmap);
                mCurrentOperationView.setFilterBitmap(currentBitmap);
            } else {
                index = mSourceBitmaps.indexOf(sourceBitmap);
                mCurrentOperationView.setFilterBitmap(currentBitmap);
                mSourceBitmaps.set(index, currentBitmap);
            }
        }
        return index;
    }

    /**
     * 取消选中编辑
     */
    public void cancelSelectEdit() {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            ICollagePathView view = (ICollagePathView) getChildAt(i);
            view.setIsTouch(false);
        }
        disableDragMode();
        mTouchMode = SELECTED_NONE;
        mCurrentOperationView = null;
    }

    /**
     * 如果是在filter mode则不需要处理任何的事件
     *
     * @param bitmap
     */
    public void setFilterBitmap(Bitmap bitmap) {
        if (mTouchMode == SELECTED_AND_EDIT && mCurrentOperationView != null && bitmap != null) {
//            if (mIsSingeleBitmapMode){
//                for (int i=0;i<getChildCount();i++){
//                    ((CollagePathView) getChildAt(i)).setFilterBitmap(bitmap);
//                }
//            }else{
            mCurrentOperationView.setFilterBitmap(bitmap);
//            }
        }
    }

    public void setFilterBitmaps(List<Bitmap> filterBitmaps) {
        if (mIsInit && filterBitmaps != null && filterBitmaps.size() > 0) {
            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                if (!(getChildAt(i) instanceof ICollagePathView)) {
                    continue;
                }
                ICollagePathView pathView = (ICollagePathView) getChildAt(i);
                if (mIsSingeleBitmapMode) {
                    pathView.setFilterBitmap(filterBitmaps.get(0));
                } else {
                    if (i < filterBitmaps.size()) {
                        pathView.setFilterBitmap(filterBitmaps.get(i));
                    }
                }
            }
        }
    }

    public ArrayList<Bitmap> getSourceBitmaps() {
        return mSourceBitmaps;
    }

    public void setFilterMode(boolean inFilterMode) {
        mInFilterMode = inFilterMode;
    }

    public void setIsFilter(boolean isFilter) {
        mIsFilter = isFilter;
    }

    public boolean isInFilterMode() {
        return mInFilterMode;
    }

    /**
     * 获取到当前选中View的SourceBitmap
     *
     * @return
     */
    public Bitmap getCurrentSourceBitmap() {
        if (mTouchMode == SELECTED_AND_EDIT && mCurrentOperationView != null) {
            return mCurrentOperationView.getSourceBitmap(0);
        }
        return null;
    }

    /**
     * 设置是否共享操作
     *
     * @param mShareOperation
     */
    public void setShareOperation(boolean mShareOperation) {
        this.mShareOperation = mShareOperation;
    }

    /**
     * 设置模式
     *
     * @param mMode
     */
    public void setMode(int mMode) {
        this.mMode = mMode;
    }

    public int getMode() {
        return mMode;
    }

    public boolean isShareOperation() {
        return mShareOperation;
    }

    public boolean isList() {
        return mIsList;
    }

    public void setList(boolean mList) {
        mIsList = mList;
    }

    //销毁
    public void destory() {
        if (mSourceBitmaps != null) {
            mSourceBitmaps.clear();
        }
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            ICollagePathView view = (ICollagePathView) getChildAt(i);
            view.onDestory();
        }
    }

    public boolean isInit() {
        return mIsInit;
    }

    /**
     * 刷新整个界面
     */
    public void invalidateListCollage(int collageWidth, int collageHeight) {
        if (mTemplet != null) {
            mChildBoundRect.clear();
            mCacheBitmap = null;
            removeAllViews();
            int count = mTemplet.getCollageNumber();
            float ratio = Ratio.SCALE_FACTOR[mType.ordinal()];
            if (collageWidth / ratio <= collageHeight) {
                mAllChildRect.left = 0;
                mAllChildRect.top = (collageHeight - collageWidth / ratio) / 2;
                mAllChildRect.right = collageWidth;
                mAllChildRect.bottom = mAllChildRect.top + collageWidth / ratio;
            } else {
                mAllChildRect.left = (collageWidth - collageHeight * ratio) / 2;
                mAllChildRect.top = 0;
                mAllChildRect.right = mAllChildRect.left + collageHeight * ratio;
                mAllChildRect.bottom = collageHeight;
            }
            for (int i = 0; i < count; i++) {
                CollagePoints collage = mTemplet.getCollagePoints(i);
                IStatus preAttr = mTemplet.getPreStatus(i);
                RectF boundRect = collage.getBoundRect();
                RectF childRect = new RectF(mAllChildRect.left + boundRect.left * mAllChildRect.width(), mAllChildRect.top + boundRect.top * mAllChildRect.height(),
                        mAllChildRect.left + boundRect.right * mAllChildRect.width(), mAllChildRect.top + boundRect.bottom * mAllChildRect.height());

                checkRectF(childRect);
                mChildBoundRect.add(childRect);
                if (mDistanceProgress == 0) {
                    Path path = RoundPathUtil.getFitPath(collage, mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
                    RectF current = new RectF(childRect);

                    LayoutParams lp = new LayoutParams((int) current.width(), (int) current.height());
                    lp.topMargin = (int) current.top;
                    lp.leftMargin = (int) current.left;

                    BitmapBean bean = null;
                    if (mBitmapBeenList != null && mBitmapBeenList.size() > 0) {
                        if (mIsSingeleBitmapMode) {
                            bean = mBitmapBeenList.get(0);
                        } else {
                            bean = mBitmapBeenList.get(i);
                        }
                    }
                    ICollagePathView pathView;
                    if (bean.mType == MediaTypeUtil.TYPE_VIDEO) {
                        CollageVideoView videoView = new CollageVideoView(getContext(), childRect, path, current, mAllChildRect, collage, preAttr);
                        videoView.setVideoPath(bean.mPath);
                        videoView.setMediaPlayerCallback(mMediaPlayerCallback, i);
                        pathView = videoView;
                    } else {
                        pathView = new CollagePathView(getContext(), childRect, path, current, mAllChildRect, collage, preAttr);
                        ((CollagePathView) pathView).setFromMirror(mFromMirror);
                        ((CollagePathView) pathView).setMediaPlayerCallback(mMediaPlayerCallback, i);
                    }
                    if (mSourceBitmaps != null && mSourceBitmaps.size() > 0) {
                        if (mIsSingeleBitmapMode) {
                            pathView.setSourceBitmap(mSourceBitmaps.get(0));
                        } else {
                            pathView.setSourceBitmap(mSourceBitmaps.get(i));
                        }
                    }
                    addView((View) pathView, lp);
                } else {
                    Path path = RoundPathUtil.getFitPath(collage, mAllChildRect.width(), mAllChildRect.height(), mRoundProgress, mDistanceProgress);
                    RectF pathBound = new RectF();
                    path.computeBounds(pathBound, false);
                    RectF current = new RectF(pathBound);
                    current.offset(mAllChildRect.left, mAllChildRect.top);

                    int width = (int) Math.ceil(current.width());
                    int height = (int) Math.ceil(current.height());
                    int left = (int) current.left;
                    int top = (int) current.top;
                    if (width + left < current.right) {
                        width += 1;
                    }
                    if (height + top < current.bottom) {
                        height += 1;
                    }
                    LayoutParams lp = new LayoutParams(width, height);
                    lp.topMargin = top;
                    lp.leftMargin = left;
                    current.set(left, top, width + left, height + top);
                    BitmapBean bean = null;
                    if (mBitmapBeenList != null && mBitmapBeenList.size() > 0) {
                        if (mIsSingeleBitmapMode) {
                            bean = mBitmapBeenList.get(0);
                        } else {
                            bean = mBitmapBeenList.get(i);
                        }
                    }
                    ICollagePathView pathView;
                    if (bean.mType == MediaTypeUtil.TYPE_VIDEO) {
                        CollageVideoView videoView = new CollageVideoView(getContext(), childRect, path, current, mAllChildRect, collage, preAttr);
                        videoView.setVideoPath(bean.mPath);
                        videoView.setMediaPlayerCallback(mMediaPlayerCallback, i);
                        pathView = videoView;
                    } else {
                        pathView = new CollagePathView(getContext(), childRect, path, current, mAllChildRect, collage, preAttr);
                        ((CollagePathView) pathView).setFromMirror(mFromMirror);
                        ((CollagePathView) pathView).setMediaPlayerCallback(mMediaPlayerCallback, i);
                    }
                    if (mSourceBitmaps != null && mSourceBitmaps.size() > 0) {
                        if (mIsSingeleBitmapMode) {
                            pathView.setSourceBitmap(mSourceBitmaps.get(0));
                        } else {
                            pathView.setSourceBitmap(mSourceBitmaps.get(i));
                        }
                    }
                    addView((View) pathView, lp);
                }
            }
            startVideo(mIsVideoPlayall);
        }
    }

//    @Override
//    public Bitmap getCurrentBitmap(long timestamp) {
//        return getCollageBitmap(timestamp);
//    }

//    public void onResume() {
//        int count = getChildCount();
//        for (int i = 0; i < count; ++i) {
//            if (!(getChildAt(i) instanceof ICollagePathView)) {
//                continue;
//            }
//            ICollagePathView view = (ICollagePathView) getChildAt(i);
//            view.onResume();
//        }
//    }

    public void onPause() {
        int count = getChildCount();
        for (int i = 0; i < count; ++i) {
            if (!(getChildAt(i) instanceof ICollagePathView)) {
                continue;
            }
            ICollagePathView view = (ICollagePathView) getChildAt(i);
            view.onPause();
        }
    }

    public void exchangeBean(BitmapBean bean1, BitmapBean bean2) {
        int index1 = 0;
        int index2 = 0;
        for (int i = 0; i < mBitmapBeenList.size(); ++i) {
            BitmapBean bean = mBitmapBeenList.get(i);
            if (bean == bean1) {
                index1 = i;
            } else if (bean == bean2) {
                index2 = i;
            }
        }
        mBitmapBeenList.remove(index1);
        mBitmapBeenList.add(index1, bean2);
        mBitmapBeenList.remove(index2);
        mBitmapBeenList.add(index2, bean1);

        Bitmap bitmap2 = mSourceBitmaps.get(index2);
        Bitmap bitmap1 = mSourceBitmaps.remove(index1);
        mSourceBitmaps.add(index1, bitmap2);
        mSourceBitmaps.remove(index2);
        mSourceBitmaps.add(index2, bitmap1);

        if (mOnBitmapExchangeListener != null) {
            mOnBitmapExchangeListener.onExchange(index1, index2);
        }
    }

    public void startVideo(final boolean playAll) {
        if (mIsVideoPlayall != playAll) {
            stopPlay();
        }
        postDelayed(new Runnable() {
            @Override
            public void run() {
                mIsVideoPlayall = playAll;
                if (playAll) {
                    startVideoPlayAll();
                } else {
                    startVideoPlayInOrder();
                }
            }
        }, 100);

    }

    public void startVideoPlayAll() {
        for (int i = 0; i < getChildCount(); ++i) {
            View child = getChildAt(i);
            if (child instanceof ICollagePathView) {
                BitmapBean bean = ((ICollagePathView) child).getBitmapBean();
                if (bean != null && (bean.mType == MediaTypeUtil.TYPE_GIF || bean.mType == MediaTypeUtil.TYPE_VIDEO)) {
                    ((ICollagePathView) child).onResume();
                }
                if (bean != null && bean.mType == MediaTypeUtil.TYPE_GIF) {
                    ((CollagePathView) child).setStartOffset(0);
                }
            }
        }
    }

    public void stopPlay() {
        for (int i = 0; i < getChildCount(); ++i) {
            View child = getChildAt(i);
            if (child instanceof ICollagePathView) {
                BitmapBean bean = ((ICollagePathView) child).getBitmapBean();
                if (bean != null && (bean.mType == MediaTypeUtil.TYPE_GIF || bean.mType == MediaTypeUtil.TYPE_VIDEO)) {
                    ((ICollagePathView) child).onPause();
                }
            }
        }
    }

    public void startVideoPlayInOrder() {
        boolean firstItem = true;
        int timeOffset = 0;
        for (int i = 0; i < getChildCount(); ++i) {
            View child = getChildAt(i);
            if (child instanceof ICollagePathView) {
                ICollagePathView videoView = (ICollagePathView) child;
                if (firstItem && videoView.getBitmapBean() != null && (videoView.getBitmapBean().mType == MediaTypeUtil.TYPE_VIDEO
                        || videoView.getBitmapBean().mType == MediaTypeUtil.TYPE_GIF)) {
                    videoView.onResume();
                    firstItem = false;
                } else {
                    if (child instanceof CollageVideoView) {
                        ((CollageVideoView) videoView).seek2Begin();
                    } else if (child instanceof CollagePathView) {
                        ((CollagePathView) videoView).seek2Begin();
                    }
                    videoView.onPause();
                }
                BitmapBean bean = videoView.getBitmapBean();
                if (bean.mType == MediaTypeUtil.TYPE_GIF || bean.mType == MediaTypeUtil.TYPE_VIDEO) {
                    if (child instanceof CollagePathView) {
                        ((CollagePathView) videoView).setStartOffset(timeOffset);
                    }
                    timeOffset += bean.mDuration;
                }
            }
        }
    }

    private boolean hasVideoorGif() {
        boolean ret = false;
        for (BitmapBean bean : mBitmapBeenList) {
            if (bean.mType == MediaTypeUtil.TYPE_VIDEO || bean.mType == MediaTypeUtil.TYPE_GIF) {
                ret = true;
                break;
            }
        }
        return ret;
    }

    public void stopVideo() {
        for (int i = 0; i < getChildCount(); ++i) {
            View view = getChildAt(i);
            if (view instanceof CollageVideoView) {
                CollageVideoView videoView = (CollageVideoView) view;
                videoView.stop();
            }
        }
    }

    public ArrayList<CombineBean> buildVideoCombineData() {
        ArrayList<CombineBean> ret = new ArrayList<>();
        int startOffset = 0;
        for (int i = 0; i < getChildCount(); ++i) {
            View view = getChildAt(i);
            if (view instanceof CollageVideoView) {
                CollageVideoView videoView = (CollageVideoView) view;
                BitmapBean bitmapBean = videoView.getBitmapBean();
                CombineBean bean = new CombineBean();
                bean.slient = videoView.isMute();
                bean.srcHeight = bitmapBean.mHeight;
                bean.srcWidth = bitmapBean.mWidth;
                bean.srcDuring = (int) bitmapBean.mDuration;
                bean.file = bitmapBean.mPath;
                bean.hasAudio = bitmapBean.mHasAudio;
                bean.startOffset = startOffset;
                if (!mIsVideoPlayall) {
                    startOffset += bean.srcDuring;
                }

                Matrix matrix = videoView.countDrawMatrix();
                float[] data = new float[9];
                matrix.getValues(data);
                Rect outputSize = getOutputSize();
                RectF rectF = new RectF(0, 0, bitmapBean.mWidth, bitmapBean.mHeight);
                matrix.mapRect(rectF);
                float currentWidth = mAllChildRect.width();
                float currentHeight = mAllChildRect.height();
                Region region = videoView.getRegion();

                float bw = bitmapBean.mWidth;
                float bh = bitmapBean.mHeight;

                Matrix oppMatrix = videoView.getOppMatrix();
                float[] oData = new float[9];
                oppMatrix.getValues(oData);
                int clipLeft;
                int clipTop;
                int clipRight;
                int clipBottom;
                float scale = outputSize.width() / currentWidth;
                Rect boundsRect = region.getBounds();
                // 生成视频后的View的边界
                RectF bounds = new RectF((float) (boundsRect.left * scale), (float) (boundsRect.top * scale),
                        (float) (boundsRect.right * scale), (float) (boundsRect.bottom * scale));
                RectF displayRect = videoView.getDisplayRect(videoView.getDrawMatrix());
                // 生成视频后的实际显示尺寸
                displayRect = new RectF((float) (displayRect.left * scale), (float) (displayRect.top * scale),
                        (displayRect.width() + displayRect.left) * scale, (displayRect.height() + displayRect.top) * scale);
                bean.scale = bounds.width() * data[0] / bw;

                float posLeft = bounds.left + 0.5f;
                float posTop = bounds.top + 0.5f;
                clipTop = 0;
                clipLeft = 0;
                if (displayRect.left > 0) {
                    posLeft += displayRect.left;
                } else {
                    clipLeft -= displayRect.left;
                }
                if (displayRect.top > 0) {
                    posTop += displayRect.top;
                } else {
                    clipTop -= displayRect.top;
                }
                if (oData[0] >= 1) {
                    clipRight = (int) (clipLeft + bounds.width());
                    clipBottom = (int) (clipTop + bounds.height());
                } else {
                    float visableW;
                    float visableH;
                    float right = displayRect.right;
                    float bottom = displayRect.bottom;
                    if (displayRect.left > 0) {
                        visableW = right - displayRect.left;
                    } else {
                        visableW = bounds.width();
                    }
                    if (displayRect.top > 0) {
                        visableH = bottom - displayRect.top;
                    } else {
                        visableH = bounds.height();
                    }
                    visableW = Math.min(visableW, bounds.width());
                    visableH = Math.min(visableH, bounds.height());
                    visableW = Math.min(visableW, bw * bean.scale);
                    visableH = Math.min(visableH, bh * bean.scale);
                    clipRight = (int) (visableW + clipLeft);
                    clipBottom = (int) (visableH + clipTop);
                }

                bean.pos = new Point((int) posLeft, (int) posTop);
                bean.clipRect = new Rect(clipLeft, clipTop, clipRight, clipBottom);
                DLog.i("winn", "scale:" + bean.scale + "  region:" + region + " pos:" + bean.pos + "  clip:" + bean.clipRect + " bound:" + bounds + " dis:" + displayRect);

                ret.add(bean);
            } else if (view instanceof ICollagePathView && !mIsVideoPlayall) {
                ICollagePathView pathView = (ICollagePathView) view;
                BitmapBean bean = pathView.getBitmapBean();
                if (bean != null && bean.mType == MediaTypeUtil.TYPE_GIF) {
                    startOffset += bean.mDuration;
                }
            }
        }
        return ret;
    }

    //返回整个图片在屏幕的位置
    public RectF getContentRectOfScreen() {
        float left = mViewRect.left + (mViewRect.width() - mAllChildRect.width()) / 2;
        float top = mViewRect.top + (mViewRect.height() - mAllChildRect.height()) / 2;
        float right = left + mAllChildRect.width();
        float bottom = top + mAllChildRect.height();
        return new RectF(left, top, right, bottom);
    }

    private OnBitmapExchangeListener mOnBitmapExchangeListener;

    public void setOnBitmapExchangeListener(OnBitmapExchangeListener onBitmapExchangeListener) {
        mOnBitmapExchangeListener = onBitmapExchangeListener;
    }

    public void setFromMirror(boolean mFromMirror) {
        this.mFromMirror = mFromMirror;
    }

    public interface OnBitmapExchangeListener {
        void onExchange(int index1, int index2);
    }

    public float getGifBgFrame() {
        if (mGifBitmap != null) {
            return mGifBitmap.getNumberOfFrames() * 1.0f / mGifBitmap.getDuration() * 1000;
        }
        return 0;
    }

    public int getVideoDuration() {
        float maxDuration = 0;
        for (BitmapBean bitmapBean : mBitmapBeenList) {
            if (bitmapBean.mDuration > maxDuration) {
                maxDuration = bitmapBean.mDuration;
            }
        }
        return (int) maxDuration;
    }

    public boolean isColorBg() {
        return mIsColorBg;
    }

    private OnCollageOperationListener mOnOperationListener;

    public void setOnOperationListener(OnCollageOperationListener onOperationListener) {
        mOnOperationListener = onOperationListener;
    }

    public interface OnCollageOperationListener {
        void onCollageOperation(boolean onOperation);
    }

    public boolean isUseBg() {
        return mUseBg;
    }

    public Ratio.RATIO getRatioType() {
        return mType;
    }
}
